package org.hk.proxy.server.channel;

import cn.hutool.core.util.StrUtil;
import io.netty.channel.Channel;
import lombok.extern.slf4j.Slf4j;
import org.hk.proxy.common.pojo.ClientConfig;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;

@Slf4j
public class ProxyChannelManager {
    private static final Map<String,Channel> cmdChannelMapping = new ConcurrentHashMap<>();
    public static final Map<Long,Channel> currentUserChannel = new ConcurrentHashMap<>();
    /**
     * 真实代理客户端和服务端的关联
     */
    public static final Map<Integer,String> clientKeyServerPort = new ConcurrentHashMap<>();

    public static final AtomicLong sidGen = new AtomicLong();


    static {
        clientKeyServerPort.put(1024,"6506955898704aa987e5b98a66985108");
        clientKeyServerPort.put(1025,"6506955898704aa987e5b98a66985107");
    }
    /**
     * 服务器配置总线
     */
    private static final List<ClientConfig> LAN_INFOS = Collections.synchronizedList(new ArrayList<>());

    public static boolean auth(String clientKey){
        for(ClientConfig config : LAN_INFOS){
            if(config.getClientKey().equalsIgnoreCase(clientKey)){
                return true;
            }
        }
        return false;
    }


    public static Long addUserChannel(Channel channel){
        Long sid =  sidGen.incrementAndGet();
        currentUserChannel.put(sid,channel);
        return sid;
    }

    public static Channel getClientChannel(String clientKey){
        return cmdChannelMapping.get(clientKey);
    }
    public static String getClientKeyByPort(Integer port){
        return  clientKeyServerPort.get(port);
    }

    public static Channel selectChannelByPort(Integer port){
        for(ClientConfig clientConfig:LAN_INFOS){
            for(ClientConfig.LanInfo lanInfo : clientConfig.getLanInfoList()){
                if(lanInfo.getServerPort().intValue()==port.intValue()){
                    return cmdChannelMapping.get(clientConfig.getClientKey());
                }
            }
        }
        return null;
    }

    public static void addLanInfo(ClientConfig ClientConfig){
        LAN_INFOS.add(ClientConfig);
    }


    public static void addCmdProxy(String clientKey,Channel proxyChannel){
        log.info("add cmd proxy,{}",clientKey);
        cmdChannelMapping.put(clientKey,proxyChannel);
    }


    public static void removeCmdProxy(Channel channel){
        String key = "";
        for(Map.Entry<String, Channel> entry: cmdChannelMapping.entrySet()){
            if(channel.equals(entry.getValue())){
                key=entry.getKey();
                break;
            }
        }
        if(StrUtil.isNotBlank(key)){
            cmdChannelMapping.remove(key);
        }
    }

    public static String getLanInfoByPort(Integer port){
        for(ClientConfig lanInfo:LAN_INFOS){
            for(ClientConfig.LanInfo  info : lanInfo.getLanInfoList()){
                if(info.getServerPort().equals(port)){
                    return info.getLanInfo();
                }
            }
        }
        return null;
    }
    public static List<Integer> returnBindPorts(){
        List<Integer> ports = new ArrayList<>();
        LAN_INFOS.forEach(LAN_INFO->{
            LAN_INFO.getLanInfoList().forEach(item->{
                ports.add(item.getServerPort());
            });
        });
        return ports;
    }
}
